home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-28  |  14.5 KB  |  795 lines

  1. /* cfengine for GNU
  2.  
  3.         Copyright (C) 1995
  4.         Free Software Foundation, Inc.
  5.  
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.  
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23.  
  24. */
  25.  
  26.  
  27.  
  28. /*******************************************************************/
  29. /*                                                                 */
  30. /*  Class string evaluation toolkit for cfengine                   */
  31. /*                                                                 */
  32. /*  Dependency: item.c toolkit                                     */
  33. /*                                                                 */
  34. /*******************************************************************/
  35.  
  36. #include "cf.defs.h"
  37. #include "cf.extern.h"
  38.  
  39.  
  40. /*********************************************************************/
  41. /* Object variables                                                  */
  42. /*********************************************************************/
  43.  
  44. char *DAYTEXT[] =
  45.    {
  46.    "Monday",
  47.    "Tuesday",
  48.    "Wednesday",
  49.    "Thursday",
  50.    "Friday",
  51.    "Saturday",
  52.    "Sunday"
  53.    };
  54.  
  55. char *MONTHTEXT[] =
  56.    {
  57.    "January",
  58.    "February",
  59.    "March",
  60.    "April",
  61.    "May",
  62.    "June",
  63.    "July",
  64.    "August",
  65.    "September",
  66.    "October",
  67.    "November",
  68.    "December"
  69.    };
  70.  
  71.  
  72. /*********************************************************************/
  73. /* Level 1                                                           */
  74. /*********************************************************************/
  75.  
  76. AddInstallable(classlist)
  77.  
  78. char *classlist;
  79.  
  80. { char *sp, currentitem[maxvarsize];
  81.  
  82. if (classlist == NULL)
  83.    {
  84.    return;
  85.    }
  86.  
  87. Debug("AddInstallable(%s)\n",classlist);
  88.   
  89.  for (sp = classlist; *sp != '\0'; sp++)
  90.    {
  91.    currentitem[0] = '\0';
  92.  
  93.    sscanf(sp,"%[^,:.]",currentitem);
  94.  
  95.    sp += strlen(currentitem);
  96.  
  97.    if (! IsItemIn(VALLADDCLASSES,currentitem))
  98.       {
  99.       AppendItem(&VALLADDCLASSES,currentitem,NULL);
  100.       }
  101.  
  102.    if (*sp == '\0')
  103.       {
  104.       break;
  105.       }
  106.    }
  107. }
  108.  
  109. /*********************************************************************/
  110.  
  111. AddMultipleClasses(classlist)
  112.  
  113. char *classlist;
  114.  
  115. { char *sp, currentitem[maxvarsize];
  116.  
  117. if ((classlist == NULL) || strlen(classlist) == 0)
  118.    {
  119.    return;
  120.    }
  121.  
  122. Debug("AddMultipleClasses(%s)\n",classlist);
  123.  
  124. for (sp = classlist; *sp != '\0'; sp++)
  125.    {
  126.    currentitem[0] = '\0';
  127.  
  128.    sscanf(sp,"%[^,:.]",currentitem);
  129.  
  130.    sp += strlen(currentitem);
  131.  
  132.    AddClassToHeap(CanonifyName(currentitem));
  133.    }
  134.  
  135. }
  136.  
  137. /*********************************************************************/
  138.  
  139. AddTimeClass(str)
  140.  
  141. char *str;
  142.  
  143. { int i;
  144.   char buf2[10], buf3[10], buf4[10], buf5[10], buf[10], out[10];
  145.   
  146. for (i = 0; i < 7; i++)
  147.    {
  148.    if (strncmp(DAYTEXT[i],str,3)==0)
  149.       {
  150.       AddClassToHeap(DAYTEXT[i]);
  151.       break;
  152.       }
  153.    }
  154.  
  155. sscanf(str,"%*s %s %s %s %s",buf2,buf3,buf4,buf5);
  156.  
  157. /* Hours */
  158.  
  159. sscanf(buf4,"%[^:]",buf);
  160. sprintf(out,"Hr%s",buf);
  161. AddClassToHeap(out);
  162.  
  163. /* Minutes */
  164.  
  165. sscanf(buf4,"%*[^:]:%[^:]",buf);
  166. sprintf(out,"Min%s",buf);
  167. AddClassToHeap(out);
  168.  
  169. sscanf(buf,"%d",&i);
  170.  
  171. switch ((i / 5))
  172.    {
  173.    case 0: AddClassToHeap("Min00_05");
  174.            break;
  175.    case 1: AddClassToHeap("Min05_10");
  176.            break;
  177.    case 2: AddClassToHeap("Min10_15");
  178.            break;
  179.    case 3: AddClassToHeap("Min15_20");
  180.            break;
  181.    case 4: AddClassToHeap("Min20_25");
  182.            break;
  183.    case 5: AddClassToHeap("Min25_30");
  184.            break;
  185.    case 6: AddClassToHeap("Min30_35");
  186.            break;
  187.    case 7: AddClassToHeap("Min35_40");
  188.            break;
  189.    case 8: AddClassToHeap("Min40_45");
  190.            break;
  191.    case 9: AddClassToHeap("Min45_50");
  192.            break;
  193.    case 10: AddClassToHeap("Min50_55");
  194.             break;
  195.    case 11: AddClassToHeap("Min55_00");
  196.             break;
  197.    }
  198.  
  199.  
  200. /* Day */
  201.  
  202. sprintf(out,"Day%s",buf3);
  203. AddClassToHeap(out);
  204.  
  205. /* Month */
  206.  
  207. for (i = 0; i < 12; i++)
  208.    {
  209.    if (strncmp(MONTHTEXT[i],buf2,3)==0)
  210.       {
  211.       AddClassToHeap(MONTHTEXT[i]);
  212.       break;
  213.       }
  214.    }
  215.  
  216. /* Year */
  217.  
  218.  strcpy(VYEAR,buf5); 
  219.  
  220. sprintf(out,"Yr%s",buf5);
  221. AddClassToHeap(out);
  222. }
  223.  
  224. /*******************************************************************/
  225.  
  226. AddClassToHeap(class)
  227.  
  228. char *class;
  229.  
  230. {
  231. Debug("AddClassToHeap(%s)\n",class);
  232. if (IsItemIn(VHEAP,class))
  233.    {
  234.    return;
  235.    }
  236.  
  237. AppendItem(&VHEAP,class,NULL);
  238. }
  239.  
  240. /*********************************************************************/
  241.  
  242. DeleteClassFromHeap(class)
  243.  
  244. char *class;
  245.  
  246. {
  247. DeleteItemMatching(&VHEAP,class);
  248. }
  249.  
  250. /*********************************************************************/
  251.  
  252. IsHardClass(sp)  /* true if string matches a hardwired class e.g. hpux */
  253.  
  254. char *sp;
  255.  
  256. { int i;
  257.  
  258. for (i = 2; CLASSTEXT[i] != '\0'; i++)
  259.    {
  260.    if (strcmp(CLASSTEXT[i],sp) == 0)
  261.       {
  262.       return(true);
  263.       }
  264.    }
  265.  
  266. for (i = 0; i < 7; i++)
  267.    {
  268.    if (strcmp(DAYTEXT[i],sp)==0)
  269.       {
  270.       return(false);
  271.       }
  272.    }
  273.  
  274. return(false);
  275. }
  276.  
  277. /*******************************************************************/
  278.  
  279. IsSpecialClass(class)
  280.  
  281. char *class;
  282.  
  283. { int value = -1;
  284.  
  285. if (strncmp(class,"IfElapsed",strlen("IfElapsed")) == 0)
  286.    {
  287.    sscanf(class,"IfElapsed%d",&value);
  288.  
  289.    if (value < 0)
  290.       {
  291.       Silent("%s: silly IfElapsed parameter in action sequence, using default...\n",VPREFIX);
  292.       return true;
  293.       }
  294.    
  295.    VIFELAPSED = value;
  296.  
  297.    Verbose("                  IfElapsed time: %d minutes\n",VIFELAPSED);
  298.    return true;
  299.    }
  300.  
  301. if (strncmp(class,"ExpireAfter",strlen("ExpireAfter")) == 0)
  302.    {
  303.    sscanf(class,"ExpireAfter%d",&value);
  304.  
  305.    if (value <= 0)
  306.       {
  307.       Silent("%s: silly ExpireAter parameter in action sequence, using default...\n",VPREFIX);
  308.       return true;
  309.       }
  310.    
  311.    VEXPIREAFTER = value;
  312.    Verbose("\n                  ExpireAfter time: %d minutes\n",VEXPIREAFTER); 
  313.    return true;
  314.    }
  315.  
  316. return false;
  317. }
  318.  
  319. /*********************************************************************/
  320.  
  321. IsExcluded(exception)
  322.  
  323. char *exception;
  324.  
  325. {
  326. if (! IsDefinedClass(exception))
  327.    {
  328.    Debug2("%s is excluded!\n",exception);
  329.    return true;
  330.    }  
  331.  
  332. return false;
  333. }
  334.  
  335. /*********************************************************************/
  336.  
  337. IsDefinedClass(class) 
  338.  
  339.   /* Evaluates a.b.c|d.e.f etc and returns true if the class */
  340.   /* is currently true, given the defined heap and negations */
  341.  
  342. char *class;
  343.  
  344. {
  345. if (class == NULL)
  346.    {
  347.    return true;
  348.    }
  349.  
  350. return EvaluateORString(class,VADDCLASSES);
  351. }
  352.  
  353.  
  354. /*********************************************************************/
  355.  
  356. IsInstallable(class)
  357.  
  358. char *class;
  359.  
  360.   /* Evaluates to true if the class string COULD become true in */
  361.   /* the course of the execution - but might not be true now    */
  362.  
  363. {
  364. return (EvaluateORString(class,VALLADDCLASSES)||EvaluateORString(class,VADDCLASSES));
  365. }
  366.  
  367.  
  368.  
  369. /*********************************************************************/
  370.  
  371. AddCompoundClass(class)
  372.  
  373. char *class;
  374.  
  375. { char *sp = class;
  376.   char cbuff[maxvarsize];
  377.  
  378. Debug1("AddCompoundClass(%s)",class);
  379.  
  380. while(*sp != '\0')
  381.    {
  382.    sscanf(sp,"%[^.]",cbuff);
  383.  
  384.    while ((*sp != '\0') && (*sp !='.'))
  385.       {
  386.       sp++;
  387.       }
  388.  
  389.    if (*sp == '.')
  390.       {
  391.       sp++;
  392.       }
  393.  
  394.    if (IsHardClass(cbuff))
  395.       {
  396.       FatalError("cfengine: You cannot use -D to define a reserved class!");
  397.       }
  398.  
  399.    AddClassToHeap(cbuff);
  400.    }
  401. }
  402.  
  403. /*********************************************************************/
  404.  
  405. NegateCompoundClass(class,heap)
  406.  
  407. char *class;
  408. struct Item **heap;
  409.  
  410. { char *sp = class;
  411.   char cbuff[maxvarsize];
  412.  
  413. Debug1("NegateCompoundClass(%s)",class);
  414.  
  415. while(*sp != '\0')
  416.    {
  417.    sscanf(sp,"%[^.]",cbuff);
  418.  
  419.    while ((*sp != '\0') && (*sp !='.'))
  420.       {
  421.       sp++;
  422.       }
  423.  
  424.    if (*sp == '.')
  425.       {
  426.       sp++;
  427.       }
  428.  
  429.    if (IsHardClass(cbuff))
  430.       { char err[bufsize];
  431.       yyerror("Illegal exception");
  432.       sprintf (err,"Cannot negate the reserved class [%s]\n",cbuff);
  433.       FatalError(err);
  434.       }
  435.  
  436.    AppendItem(heap,cbuff,NULL);
  437.    }
  438. }
  439.  
  440. /*********************************************************************/
  441. /* Level 2                                                           */
  442. /*********************************************************************/
  443.  
  444. EvaluateORString(class,list)
  445.  
  446. char *class;
  447. struct Item *list;
  448.  
  449. { char *sp, cbuff[bufsize];
  450.   int result = false;
  451.  
  452. for (sp = class; *sp != '\0'; sp++)
  453.    {
  454.    while (*sp == '|')
  455.       {
  456.       sp++;
  457.       }
  458.  
  459.    bzero(cbuff,bufsize);
  460.  
  461.    sp += GetORAtom(sp,cbuff);
  462.  
  463.    if (strlen(cbuff) == 0)
  464.       {
  465.       break;
  466.       }
  467.  
  468.    if (IsBracketed(cbuff)) /* Strip brackets */
  469.       {
  470.       cbuff[strlen(cbuff)-1] = '\0';
  471.  
  472.       result |= EvaluateORString(cbuff+1,list);
  473.       }
  474.    else
  475.       {
  476.       result |= EvaluateANDString(cbuff,list);
  477.       }
  478.  
  479.    if (*sp == '\0')
  480.       {
  481.       break;
  482.       }
  483.    }
  484.  
  485. return result;
  486. }
  487.  
  488. /*********************************************************************/
  489. /* Level 3                                                           */
  490. /*********************************************************************/
  491.  
  492. EvaluateANDString(class,list)
  493.  
  494. char *class;
  495. struct Item *list;
  496.  
  497. { char *sp, *atom;
  498.   char cbuff[bufsize];
  499.   int count = 1, brackets = 0;
  500.   int negation = false;
  501.  
  502. count = CountEvalAtoms(class);
  503. sp = class;
  504.  
  505. while(*sp != '\0')
  506.    {
  507.    negation = false;
  508.  
  509.    while (*sp == '!')
  510.       {
  511.       negation = !negation;
  512.       sp++;
  513.       }
  514.  
  515.    bzero(cbuff,bufsize);
  516.  
  517.    sp += GetANDAtom(sp,cbuff) + 1;
  518.  
  519.    atom = cbuff;
  520.  
  521.      /* Test for parentheses */
  522.    
  523.    if (IsBracketed(cbuff))
  524.       {
  525.       atom = cbuff+1;
  526.  
  527.       cbuff[strlen(cbuff)-1] = '\0';
  528.  
  529.       if (EvaluateORString(atom,list))
  530.      {
  531.      if (negation)
  532.         {
  533.         return false;
  534.         }
  535.      else
  536.         {
  537.         count--;
  538.         }
  539.      }
  540.       else
  541.      {
  542.      if (negation)
  543.         {
  544.         count--;
  545.         }
  546.      else
  547.         {
  548.         return false;
  549.         }
  550.      }
  551.  
  552.       continue;
  553.       }
  554.    else
  555.       {
  556.       atom = cbuff;
  557.       }
  558.    
  559.    /* End of parenthesis check */
  560.    
  561.    if (*sp == '.')
  562.       {
  563.       sp++;
  564.       }
  565.  
  566.    if (IsItemIn(VNEGHEAP,atom))
  567.       {
  568.       if (negation)
  569.          {
  570.      count--;
  571.      }
  572.       else
  573.      {
  574.      return false;
  575.      }
  576.       } 
  577.    else if (IsItemIn(VHEAP,atom))
  578.       {
  579.       if (negation)
  580.          {
  581.      return false;
  582.          }
  583.       else
  584.          {
  585.          count--;
  586.          }
  587.       } 
  588.    else if (IsItemIn(list,atom))
  589.       {
  590.       if (negation)
  591.          {
  592.          return false;
  593.          }
  594.       else
  595.          {
  596.          count--;
  597.          }
  598.       } 
  599.    else if (negation)    /* ! (an undefined class) == true */
  600.       {
  601.       count--;
  602.       }
  603.    else
  604.       {
  605.       return false;
  606.       }
  607.    }
  608.  
  609. if (count == 0)
  610.    {
  611.    return(true);
  612.    }
  613. else
  614.    {
  615.    return(false);
  616.    }
  617. }
  618.  
  619. /*********************************************************************/
  620.  
  621. GetORAtom(start,buffer)
  622.  
  623. char *start, *buffer;
  624.  
  625. { char *sp = start;
  626.   char *spc = buffer;
  627.   int bracklevel = 0, len = 0;
  628.  
  629. while ((*sp != '\0') && !((*sp == '|') && (bracklevel == 0)))
  630.    {
  631.    if (*sp == '(')
  632.       {
  633.       bracklevel++;
  634.       }
  635.  
  636.    if (*sp == ')')
  637.       {
  638.       bracklevel--;
  639.       }
  640.  
  641.    *spc++ = *sp++;
  642.    len++;
  643.    }
  644.  
  645. *spc = '\0';
  646.  
  647. return len;
  648. }
  649.  
  650. /*********************************************************************/
  651. /* Level 4                                                           */
  652. /*********************************************************************/
  653.  
  654. GetANDAtom(start,buffer)
  655.  
  656. char *start, *buffer;
  657.  
  658. { char *sp = start;
  659.   char *spc = buffer;
  660.   int bracklevel = 0, len = 0;
  661.  
  662. while ((*sp != '\0') && !((*sp == '.') && (bracklevel == 0)))
  663.    {
  664.    if (*sp == '(')
  665.       {
  666.       bracklevel++;
  667.       }
  668.  
  669.    if (*sp == ')')
  670.       {
  671.       bracklevel--;
  672.       }
  673.  
  674.    *spc++ = *sp++;
  675.  
  676.    len++;
  677.    }
  678.  
  679. *spc = '\0';
  680.  
  681. return len;
  682. }
  683.  
  684. /*********************************************************************/
  685.  
  686. CountEvalAtoms(class)
  687.  
  688. char *class;
  689.  
  690. { char *sp;
  691.   int count = 0, bracklevel = 0;
  692.   
  693. for (sp = class; *sp != '\0'; sp++)
  694.    {
  695.    if (*sp == '(')
  696.       {
  697.       bracklevel++;
  698.       continue;
  699.       }
  700.  
  701.    if (*sp == ')')
  702.       {
  703.       bracklevel--;
  704.       continue;
  705.       }
  706.    
  707.    if ((bracklevel == 0) && (*sp == '.'))
  708.       {
  709.       count++;
  710.       }
  711.    }
  712.  
  713. if (bracklevel != 0)
  714.    {
  715.    sprintf(OUTPUT,"Bracket mismatch, in [class=%s], shouldn't happen, level = %d\n",class,bracklevel);
  716.    CfLog(cferror,OUTPUT,"");
  717.    FatalError("Aborted");
  718.    }
  719.  
  720. return count+1;
  721. }
  722.  
  723. /*********************************************************************/
  724. /* TOOLKIT : actions                                                 */
  725. /*********************************************************************/
  726.  
  727. enum actions ActionStringToCode (str)
  728.  
  729. char *str;
  730.  
  731. { char *sp;
  732.   int i;
  733.  
  734. ACTION = none;
  735.  
  736. for (sp = str; *sp != '\0'; sp++)
  737.    {
  738.    *sp = ToLower(*sp);
  739.    }
  740.  
  741. for (i = 1; ACTIONID[i] != '\0'; i++)
  742.    {
  743.    if (strcmp(ACTIONID[i],str) == 0)
  744.       {
  745.       ACTION = (enum actions) i;
  746.       break;
  747.       }
  748.    }
  749.  
  750. if (ACTION == none)
  751.   {
  752.   yyerror("Indexed macro specified no action");
  753.   FatalError("Could not compile action");
  754.   }
  755.  
  756. return (enum actions) i;
  757. }
  758.  
  759. /*********************************************************************/
  760.  
  761. IsBracketed(s)
  762.  
  763.  /* return true if the entire string is bracketed, not just if
  764.     if contains brackets */
  765.  
  766. char *s;
  767.  
  768. { int i, level= 0;
  769.  
  770. if (*s != '(')
  771.    {
  772.    return false;
  773.    }
  774.  
  775. for (i = 0; i < strlen(s)-1; i++)
  776.    {
  777.    if (s[i] == '(')
  778.       {
  779.       level++;
  780.       }
  781.    
  782.    if (s[i] == ')')
  783.       {
  784.       level--;
  785.       }
  786.  
  787.    if (level == 0)
  788.       {
  789.       return false;  /* premature ) */
  790.       }
  791.    }
  792.  
  793. return true;
  794. }
  795.